
#ifndef RTHTTPUTILCLASSES_H
#define RTHTTPUTILCLASSES_H

#include "RtReferenceControl.h"
#include "RtMutex.h"
#include "RtUtilTemplates.h"
#include <set>

enum /*RT_API_EXPORT*/ CRtHttpVersion 
{
	HttpVersion_Unknow = 0, 
	HttpVersion_0_9 = 9, 
	HttpVersion_1_0 = 10, 
	HttpVersion_1_1 = 11
};

class /*RT_API_EXPORT*/ CRtHttpAtom
{
public:
	explicit CRtHttpAtom(LPCSTR aVal = NULL) : m_strVal(aVal) { }
	CRtHttpAtom(const CRtHttpAtom &aAtom) { m_strVal = aAtom.m_strVal; }

	operator LPCSTR () const { return m_strVal; }
	LPCSTR get() const { return m_strVal; }

	void operator=(LPCSTR v) { m_strVal = v; }
	void operator=(const CRtHttpAtom &aAtom) { m_strVal = aAtom.m_strVal; }

	bool operator < (const CRtHttpAtom &aRight) const
	{ 
/*		size_t nLen1 = m_strVal ? strlen(m_strVal) : 0;
		size_t nLen2 = aRight.m_strVal ? strlen(aRight.m_strVal) : 0;
		size_t nLen = std::min(nLen1, nLen2);
		
		int nRet = ::memcmp(m_strVal, aRight.m_strVal, nLen);
		if (!nRet)
			nRet = nLen1 - nLen2;
*/
		int nRet = strcasecmp(m_strVal, aRight.m_strVal);
		return nRet < 0;
	}

private:
	LPCSTR m_strVal;
};

class RT_NW_EXPORT/*RT_API_EXPORT*/ CRtHttpAtomList
{
public:
	static CRtHttpAtomList* Instance();

	CRtHttpAtom ResolveAtom(const CRtString &aValue, BOOL bAdd = TRUE);

#define HTTP_ATOM(name, value) static CRtHttpAtom name;
#include "RtHttpAtomList.h"
#undef HTTP_ATOM

private:
	CRtHttpAtomList();
	~CRtHttpAtomList();

	void CreateAtomTable();
	typedef std::set<CRtHttpAtom> AtomTablesType;
	AtomTablesType s_AtomTables;
	BOOL s_bAtomTableCreated;

	std::vector<char*> m_newAtoms;

	typedef CRtMutexThread MutexType;
	MutexType m_mutex;

	friend class CRtSingletonT<CRtHttpAtomList>;
};

class RT_API_EXPORT CRtHttpProxyInfo : public CRtReferenceControlMutilThread
{
public:
	typedef enum {
		HTTP_PROXY = 1,
		HTTPS_PROXY,
		SOCK4_PROXY,
		SOCK5_PROXY
	} PROXY_TYPE;
	
	CRtHttpProxyInfo();

	RtResult Init(const CRtString &aHostAndPort, PROXY_TYPE aType);
	RtResult Init(const CRtString &aHost, WORD aPort, PROXY_TYPE aType);

	BOOL Equal(const CRtHttpProxyInfo& aRight);
	
	inline CRtString GetAuthScheme() const { return m_strAuthScheme; }
	inline CRtString GetHostName() const { return m_strHostName; }
	inline WORD GetPort() const { return m_wPort; }
	inline void SetAuthScheme(const CRtString &aScheme) {	m_strAuthScheme = aScheme; }

	inline PROXY_TYPE GetProxyType() const	{ return m_nType; }

	inline CRtString GetUserName() const { return m_strUserName; }
	inline void SetUserName(const CRtString &aUserName) { m_strUserName = aUserName; }
	inline CRtString GetPasswd() const { return m_strPasswd; }
	inline void SetPasswd(const CRtString &aPasswd){ m_strPasswd = aPasswd; }

	inline BOOL IsFirstTryWithoutUserName() const { return m_bFirstTryWithoutUserName; }
	inline void SetFirstTryedWithoutUserName() { m_bFirstTryWithoutUserName = FALSE; }
	
private:
	CRtString	m_strUserName;
	CRtString	m_strPasswd;
	CRtString	m_strAuthScheme;
	CRtString	m_strHostName;
	WORD		m_wPort;
	BOOL		m_bFirstTryWithoutUserName;
	PROXY_TYPE	m_nType;
};

#endif // !RTHTTPUTILCLASSES_H
